import { ReactNode, useEffect } from 'react';
import { Navigate, useLocation } from 'react-router-dom';
import { useAppSelector, useAppDispatch } from '@/store';
import { getCurrentUser } from '@/store/slices/authSlice';
import { requiresAuth, isPublicRoute } from './routes';
import { windowService } from '@/services/window';

interface AuthGuardProps {
  children: ReactNode;
}

// Authentication Guard Component
export const AuthGuard: React.FC<AuthGuardProps> = ({ children }) => {
  const location = useLocation();
  const dispatch = useAppDispatch();
  const { isAuthenticated, isLoading, user } = useAppSelector(state => state.auth);

  useEffect(() => {
    // If we have a token but no user, try to fetch user info
    if (!isLoading && !user && !isAuthenticated) {
      const token = localStorage.getItem('auth_token');
      if (token) {
        dispatch(getCurrentUser());
      }
    }
  }, [dispatch, isLoading, user, isAuthenticated]);

  // 设置窗口限制
  useEffect(() => {
    const currentPath = location.pathname;
    requiresAuth(currentPath);
    const isPublic = isPublicRoute(currentPath);

    const setupWindowConstraints = async () => {
      if (isPublic && !isAuthenticated) {
        // 登录页面：禁止调整大小，固定尺寸，只能最小化和关闭
        await windowService.setResizable(false);
        await windowService.setSize(1000, 700);
        await windowService.center();
      } else if (isAuthenticated) {
        // 登录后：允许调整大小，最大化
        await windowService.setResizable(true);
        await windowService.maximize();
      }
    };

    setupWindowConstraints();
  }, [location.pathname, isAuthenticated]);

  // Show loading while checking authentication
  if (isLoading) {
    return (
      <div className='flex justify-center items-center min-h-screen'>
        <div className='loading-spinner' />
      </div>
    );
  }

  const currentPath = location.pathname;
  const routeRequiresAuth = requiresAuth(currentPath);
  const isPublic = isPublicRoute(currentPath);

  // 开发模式：暂时允许访问所有页面，绕过认证检查
  const isDevelopment = process.env.NODE_ENV === 'development';

  // 应用启动时直接跳转到仪表板，绕过认证检查
  if (currentPath === '/' || currentPath === '/auth/login') {
    return <Navigate to='/dashboard' replace />;
  }

  // If route requires auth and user is not authenticated
  if (routeRequiresAuth && !isAuthenticated && !isDevelopment) {
    return <Navigate to='/auth/login' state={{ from: currentPath }} replace />;
  }

  // If user is authenticated and trying to access auth pages
  if (isAuthenticated && isPublic) {
    return <Navigate to='/dashboard' replace />;
  }

  return <>{children}</>;
};

interface PublicGuardProps {
  children: ReactNode;
}

// Public Route Guard (for auth pages when already authenticated)
export const PublicGuard: React.FC<PublicGuardProps> = ({ children }) => {
  const { isAuthenticated } = useAppSelector(state => state.auth);

  if (isAuthenticated) {
    return <Navigate to='/dashboard' replace />;
  }

  return <>{children}</>;
};

interface AdminGuardProps {
  children: ReactNode;
  fallback?: ReactNode;
}

// Admin Role Guard
export const AdminGuard: React.FC<AdminGuardProps> = ({
  children,
  fallback = <Navigate to='/dashboard' replace />,
}) => {
  const { user, isAuthenticated } = useAppSelector(state => state.auth);

  if (!isAuthenticated || !user) {
    return <Navigate to='/auth/login' replace />;
  }

  if (user.role !== 'admin') {
    return <>{fallback}</>;
  }

  return <>{children}</>;
};

interface PermissionGuardProps {
  children: ReactNode;
  permissions: string[];
  requireAll?: boolean;
  fallback?: ReactNode;
}

// Permission-based Guard
export const PermissionGuard: React.FC<PermissionGuardProps> = ({
  children,
  permissions,
  requireAll = false,
  fallback = <div>Access Denied</div>,
}) => {
  const { user, isAuthenticated } = useAppSelector(state => state.auth);

  if (!isAuthenticated || !user) {
    return <Navigate to='/auth/login' replace />;
  }

  // For now, we'll implement basic role-based permissions
  // This can be extended based on your permission system
  const userPermissions = getUserPermissions(user.role);

  const hasPermission = requireAll
    ? permissions.every(permission => userPermissions.includes(permission))
    : permissions.some(permission => userPermissions.includes(permission));

  if (!hasPermission) {
    return <>{fallback}</>;
  }

  return <>{children}</>;
};

// Helper function to get permissions based on user role
function getUserPermissions(role: string): string[] {
  const rolePermissions = {
    admin: [
      'view_analytics',
      'manage_users',
      'system_settings',
      'batch_process',
      'video_edit',
      'export_data',
    ],
    moderator: ['view_analytics', 'batch_process', 'video_edit', 'export_data'],
    user: ['video_edit', 'batch_process'],
  };

  return rolePermissions[role as keyof typeof rolePermissions] || [];
}
